import subprocess
import os
import sys
import time
import threading

# 项目根目录、流目录和临时文件定义
PROJECT_DIR = os.path.dirname(os.path.abspath(__file__))
STREAM_DIR = os.path.join(PROJECT_DIR, 'stream')
TEMP_MKV = os.path.join(PROJECT_DIR, 'temp.mkv')

# 检查命令是否可用
def check_command_available(command):
    print(f"正在检查 {command} 是否可用...")
    try:
        # 先尝试直接运行命令
        version = ''
        if command == 'ffmpeg':
            version = '-version'
        else:
            version = '--version'
        result = subprocess.run(
            [command, version],
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            timeout=5
        )
        if result.returncode == 0:
            print(f"[+] 找到 {command} 工具")
            return True, command  # 返回命令和是否可用
        else:
            print(f"[-] 未找到 {command} 工具")
            return False, None  # 返回是否可用和命令
    except (FileNotFoundError, subprocess.TimeoutExpired):
        return False, None  # 返回是否可用和命令

# 检查ADB是否可用
def check_adb_available():
    return check_command_available('adb')

# 创建流目录
def create_stream_dir():
    if not os.path.exists(STREAM_DIR):
        os.makedirs(STREAM_DIR)
        print(f"已创建流目录: {STREAM_DIR}")
    else:
        print(f"流目录已存在: {STREAM_DIR}")

# 检查设备是否连接
def check_device_connected():
    try:
        devices_result = subprocess.run(
            ['adb', 'devices'],
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            text=True,
            timeout=5
        )
        return 'device' in devices_result.stdout
    except Exception as e:
        print(f"检查设备连接时出错: {e}")
        return False

# 启动scrcpy进程
def start_scrcpy(scrcpy_path):
    # 删除可能存在的旧临时文件
    if os.path.exists(TEMP_MKV):
        try:
            os.remove(TEMP_MKV)
            print(f"已删除旧的临时文件: {TEMP_MKV}")
        except Exception as e:
            print(f"删除旧临时文件失败: {e}")
    
    # 配置scrcpy命令 - 完全按照用户提供的成功命令
    scrcpy_cmd = [
        scrcpy_path,
        '--record', TEMP_MKV,
        '-m', '1080'
    ]
    print(f"执行scrcpy命令: {' '.join(scrcpy_cmd)}")
    
    # 启动scrcpy进程
    scrcpy_process = subprocess.Popen(
        scrcpy_cmd,
        stdout=subprocess.PIPE,
        stderr=subprocess.STDOUT  # 合并 stdout 和 stderr
    )
    
    return scrcpy_process

# 启动ffmpeg进程
def start_ffmpeg(ffmpeg_path):
    # 配置ffmpeg命令 - 完全按照用户提供的成功命令
    ffmpeg_cmd = [
        ffmpeg_path,
        '-re',
        '-i', TEMP_MKV,
        '-c:v', 'copy',
        '-c:a', 'aac',
        '-f', 'hls',
        '-hls_time', '2',
        '-hls_list_size', '5',
        '-y',
        os.path.join(STREAM_DIR, 'stream.m3u8')
    ]
    print(f"执行ffmpeg命令: {' '.join(ffmpeg_cmd)}")
    
    # 启动ffmpeg进程
    ffmpeg_process = subprocess.Popen(
        ffmpeg_cmd,
        stdout=subprocess.PIPE,
        stderr=subprocess.STDOUT  # 合并 stdout 和 stderr
    )
    
    return ffmpeg_process

# 监控进程输出
def monitor_process(process, process_name):
    while True:
        line = process.stdout.readline().decode('utf-8', errors='ignore')
        if not line and process.poll() is not None:
            break
        if line:
            print(f"[{process_name}] {line.strip()}")
    
    if process.poll() != 0:
        print(f"警告: {process_name}进程异常退出，返回代码: {process.returncode}")

# 等待临时文件创建并写入数据
def wait_for_temp_file():
    print("等待临时文件创建并写入数据...")
    wait_time = 0
    while not os.path.exists(TEMP_MKV):
        if wait_time >= 10:
            print(f"错误: 临时文件 {TEMP_MKV} 未能在10秒内创建")
            return False
        print(f"等待临时文件创建，已等待 {wait_time} 秒...")
        time.sleep(1)
        wait_time += 1
    
    # 等待文件写入一些数据
    data_wait_time = 0
    while os.path.getsize(TEMP_MKV) < 1024 * 10:  # 等待文件至少有10KB数据
        if data_wait_time >= 10:
            print(f"警告: 临时文件 {TEMP_MKV} 数据写入较慢，但仍尝试继续...")
            break
        print(f"等待临时文件写入数据，已等待 {data_wait_time} 秒，当前大小: {os.path.getsize(TEMP_MKV)} 字节")
        time.sleep(1)
        data_wait_time += 1
    
    print(f"临时文件已准备好: {TEMP_MKV}, 大小: {os.path.getsize(TEMP_MKV)} 字节")
    return True

# 主函数
def main():
    print("=== 简单投屏脚本 - 基于用户提供的成功命令 ===")
    
    # 检查必要的命令是否可用
    adb_available, adb_path = check_adb_available()
    if not adb_available:
        print("错误: 未找到ADB工具。请确保Android SDK已安装并将adb添加到系统路径中。")
        sys.exit(1)
    
    scrcpy_available, scrcpy_path = check_command_available('scrcpy')
    if not scrcpy_available:
        print("错误: 未找到scrcpy工具。请安装scrcpy并添加到系统路径中。")
        sys.exit(1)
    
    ffmpeg_available, ffmpeg_path = check_command_available('ffmpeg')
    if not ffmpeg_available:
        print("错误: 无法继续，因为未找到ffmpeg工具。")
        sys.exit(1)
    
    # 检查设备是否连接
    if not check_device_connected():
        print("错误: 未检测到已连接的Android设备。请确保设备已通过USB连接并已启用USB调试。")
        sys.exit(1)
    
    # 创建流目录
    create_stream_dir()
    
    # 启动scrcpy进程
    scrcpy_process = start_scrcpy(scrcpy_path)
    if not scrcpy_process:
        print("错误: 无法启动scrcpy进程")
        sys.exit(1)
    
    # 启动scrcpy监控线程
    scrcpy_monitor = threading.Thread(target=monitor_process, args=(scrcpy_process, 'scrcpy'))
    scrcpy_monitor.daemon = True
    scrcpy_monitor.start()
    
    # 等待临时文件创建
    if not wait_for_temp_file():
        scrcpy_process.terminate()
        sys.exit(1)
    
    # 启动ffmpeg进程
    ffmpeg_process = start_ffmpeg(ffmpeg_path)
    if not ffmpeg_process:
        print("错误: 无法启动ffmpeg进程")
        scrcpy_process.terminate()
        sys.exit(1)
    
    # 启动ffmpeg监控线程
    ffmpeg_monitor = threading.Thread(target=monitor_process, args=(ffmpeg_process, 'ffmpeg'))
    ffmpeg_monitor.daemon = True
    ffmpeg_monitor.start()
    
    print("\n=== 投屏服务已启动 ===")
    print("按 Ctrl+C 停止服务...")
    
    try:
        # 保持主进程运行
        while True:
            # 检查流文件是否生成
            m3u8_path = os.path.join(STREAM_DIR, 'stream.m3u8')
            if os.path.exists(m3u8_path):
                print(f"流文件已生成: {m3u8_path}, 大小: {os.path.getsize(m3u8_path)} 字节")
                # 检查是否有ts分片文件
                ts_files = [f for f in os.listdir(STREAM_DIR) if f.endswith('.ts')]
                if ts_files:
                    print(f"找到 {len(ts_files)} 个TS分片文件")
                else:
                    print("流目录中未找到TS分片文件")
            else:
                print(f"流文件尚未生成: {m3u8_path}")
            
            time.sleep(5)
            
    except KeyboardInterrupt:
        print("\n正在停止所有服务...")
    finally:
        # 停止所有进程
        if scrcpy_process:
            try:
                scrcpy_process.terminate()
            except Exception:
                pass
        
        if ffmpeg_process:
            try:
                ffmpeg_process.terminate()
            except Exception:
                pass
        
        print("所有服务已停止")

if __name__ == "__main__":
    main()